require('dotenv').config();

const Koa = require('koa')
const cors = require('kcors')
const statics = require('koa-static')
const config = require('config')
const { createClient } = require("webdav");
const app = module.exports = new Koa();
const fs = require('fs');
const router = new require('koa-router')()
const jwt = require('jsonwebtoken')
const clientKey = config.get('clientKey')
const logger = require('koa-pino-logger')()
const fundebug = require("fundebug-nodejs");
fundebug.apikey=process.env['fundebugApiKey']

app.use(cors())
app.use((statics('../webapp')))

app.use(async function(ctx, next) {
    try {
        const start = new Date();
        await next();
        if(ctx.meta&&ctx.meta.summary){
            ctx.response.append('OperationType',ctx.meta.summary)
        }
        if(ctx.user&&ctx.user.phone){
            ctx.response.append('UserPhone',ctx.user.phone)
        }
        const ms = new Date() - start;
        if(process.env['NODE_ENV']=='development') {
            console.log('%s %s - %s ms', ctx.method, ctx.originalUrl, ms);
        }
    } catch (error) {
        ctx.status = error.status || 500;
        ctx.body = error.message||error;
        if(process.env['NODE_ENV']=='development'){
            console.error('%s %s - %s', ctx.method,ctx.originalUrl, error.stack || error)
        }
        if(process.env['NODE_ENV']=='production'){
            fundebug.notify("cmap", error.stack || error)
        }
    }
});


app.silent = true
if(process.env['NODE_ENV']=='production') {
    app.use(logger)
}

router.get(['/login','/register','/reset','/'], async (ctx, next) => {
    ctx.type = 'html';
    ctx.body = fs.createReadStream('../webapp/index.html');
})

app.use(router.routes()).use(router.allowedMethods());

const needCheckToken = (ctx)=>{
    if(ctx.path.match(/shares\/public/)
        ||ctx.path.match(/login/)
        ||(ctx.path.match(/register/)&&!ctx.path.match(/deregister/))
        ||ctx.path.match(/reset/)
        ||ctx.path.match(/smscode/)
        ||(ctx.path.match(/swagger/))){
        return false
    }
    return true;
}

app.use(async function(ctx,next){
    if(needCheckToken(ctx)){
        let token = ctx.req.headers['token']||ctx.req.headers['authorization']
            ||ctx.cookies.get('token')||ctx.cookies.get('authorization');
        let error = new Error();
        error.status = 401;
        if(!token){
            error.message = 'no token found!'
            ctx.throw(error)
        }else{
            const webdav_path = `/remote.php/dav`;
            let user;
            try{
                user = jwt.verify(token,clientKey)
                user.id = user.id||user.phone
            }catch(err){
                error.message = err.message
                ctx.throw(error)
            }
            if(!user){
                error.message = `user ${token} not found!`
                ctx.throw(error)
            }
            let client = createClient(
                `${config.get('nextcloud.host')}${webdav_path}`,
                {username:user.phone, password:user.passwd}
            )
            ctx.client = client
            ctx.user = user
            await next();
        }
    }else{
        await next();
    }
})

const router_v2 = require('./route/v2').default;
app.use(router_v2.routes()).use(router_v2.allowedMethods());

app.on("error", fundebug.KoaErrorHandler);

if (!module.parent) app.listen(config.get('port'),async ()=>{
    logger.logger.info('server started!')
});
